#include "Board.h"
#ifndef TEST_H
#define TEST_H
bool testGetValue1(){
	Board board;
	board.setSize(15);
	board.setValue(3, 4, OUR_TYPE);
	board.setValue(3, 5, OUR_TYPE);
	board.setValue(3, 6, OUR_TYPE);

	return board.getValue(3, 4, HORIZONTAL, 0) == OUR_TYPE;
}
bool testGetValue2(){
	Board board;
	board.setSize(15);
	board.setValue(3, 4, OUR_TYPE);
	board.setValue(3, 5, OUR_TYPE);
	board.setValue(3, 6, OUR_TYPE);

	//cout << board;
	return
		board.getValue(3, 4, HORIZONTAL, 1) == OUR_TYPE;
}
bool testGetValueDiagonal2Left(){
	Board board;
	board.setSize(15);
	board.setValue(3, 4, OUR_TYPE);
	board.setValue(3, 5, OUR_TYPE);
	board.setValue(3, 6, OUR_TYPE);
	board.setValue(5, 4, OUR_TYPE);

	return
		board.getValue(3, 6, DIAGONAL2, -2) == OUR_TYPE;
}
bool testGetValueDiagonal2Right(){
	Board board;
	board.setSize(15);
	board.setValue(3, 4, OUR_TYPE);
	board.setValue(3, 5, OUR_TYPE);
	board.setValue(3, 6, OUR_TYPE);
	board.setValue(2, 7, OUR_TYPE);
	//cout << board;
	return
		board.getValue(3, 6, DIAGONAL2, 1) == OUR_TYPE;
}
bool testGetValueDiagonal1Left(){
	Board board;
	board.setSize(15);
	board.setValue(5, 6, OUR_TYPE);
	board.setValue(3, 4, OUR_TYPE);

	//cout << board;
	return
		board.getValue(5, 6, DIAGONAL1, -2) == OUR_TYPE;
}
bool testGetValueDiagonal1Right(){
	Board board;
	board.setSize(15);
	board.setValue(5, 6, OUR_TYPE);
	board.setValue(3, 4, OUR_TYPE);

	//cout << board;
	return
		board.getValue(3, 4, DIAGONAL1, 2) == OUR_TYPE;
}

bool checkOpenThreeHorizontal(vector<Vec2>vGain){

	vector<Vec2> vExpectedGain;
	vExpectedGain.push_back(Vec2(3, 3));
	vExpectedGain.push_back(Vec2(3, 7));
	for each (Vec2 v in vExpectedGain)
	{
		vector < Vec2 >::iterator a = find(vGain.begin(), vGain.end(), v);
		if (a == vGain.end())
			return false;
	}
	return true;
}
bool testOpenThreeHorizontalCurrentAtFirst(){
	Board board;
	board.setSize(15);
	board.setValue(3, 4, OUR_TYPE);
	board.setValue(3, 5, OUR_TYPE);
	board.setValue(3, 6, OUR_TYPE);
	vector<Vec2> vGain;
	board.findGain(3, 4, OUR_TYPE, HORIZONTAL, vGain);

	return checkOpenThreeHorizontal(vGain);


}
bool testOpenThreeHorizontalCurrentAtSecond(){
	Board board;
	board.setSize(15);
	board.setValue(3, 4, OUR_TYPE);
	board.setValue(3, 5, OUR_TYPE);
	board.setValue(3, 6, OUR_TYPE);
	vector<Vec2> vGain;
	board.findGain(3, 5, OUR_TYPE, HORIZONTAL, vGain);
	return checkOpenThreeHorizontal(vGain);
}
bool testOpenThreeHorizontalCurrentAtThird(){
	Board board;
	board.setSize(15);
	board.setValue(3, 4, OUR_TYPE);
	board.setValue(3, 5, OUR_TYPE);
	board.setValue(3, 6, OUR_TYPE);
	vector<Vec2> vGain;
	board.findGain(3, 6, OUR_TYPE, HORIZONTAL, vGain);
	return checkOpenThreeHorizontal(vGain);
}
void initFourOpenDiagonal1Test(Board &board){

	board.setSize(15);
	board.setValue(2, 6, OUR_TYPE);
	board.setValue(3, 7, OUR_TYPE);
	board.setValue(4, 8, OUR_TYPE);
	board.setValue(5, 9, OUR_TYPE);
}
bool checkGainFourOpenDiagonal1(vector<Vec2>&vGain){
	if (vGain.size() == 0)
		return false;
	vector<Vec2> vExpectedGain;
	vExpectedGain.push_back(Vec2(1, 5));
	vExpectedGain.push_back(Vec2(6, 10));
	for each (Vec2 v in vExpectedGain)
	{
		vector < Vec2 >::iterator a = find(vGain.begin(), vGain.end(), v);
		if (a == vGain.end())
			return false;
	}
	return true;
}
bool testFourOpenDiagonal1CurrentAtFirst(){
	Board board;
	initFourOpenDiagonal1Test(board);

	vector<Vec2> vGain;
	board.findGain(2, 6, OUR_TYPE, DIAGONAL1, vGain);
	return checkGainFourOpenDiagonal1(vGain);
}
bool testFourOpenDiagonal1CurrentAtSecond(){
	Board board;
	initFourOpenDiagonal1Test(board);
	vector<Vec2> vGain;
	board.findGain(3, 7, OUR_TYPE, DIAGONAL1, vGain);
	return checkGainFourOpenDiagonal1(vGain);
}
bool testFourOpenDiagonal1CurrentAtThird(){
	Board board;
	initFourOpenDiagonal1Test(board);
	vector<Vec2> vGain;
	board.findGain(4, 8, OUR_TYPE, DIAGONAL1, vGain);
	return checkGainFourOpenDiagonal1(vGain);
}
bool testFourOpenDiagonal1CurrentAtFourth(){
	Board board;
	initFourOpenDiagonal1Test(board);
	vector<Vec2> vGain;
	board.findGain(5, 9, OUR_TYPE, DIAGONAL1, vGain);
	return checkGainFourOpenDiagonal1(vGain);
}
void initFourBlockDiagonal2(Board &board){
	board.setSize(15);

	board.setValue(2, 6, OUR_TYPE);
	board.setValue(3, 7, OUR_TYPE);
	board.setValue(4, 8, OUR_TYPE);
	board.setValue(5, 9, OUR_TYPE);
	board.setValue(5, 5, ENEMY_TYPE);
	board.setValue(6, 4, OUR_TYPE);
	board.setValue(7, 3, OUR_TYPE);
	board.setValue(8, 2, OUR_TYPE);
	board.setValue(9, 1, OUR_TYPE);

}
bool checkGainFourBlockDiagonal2(vector<Vec2> &vGain){

	for each (Vec2 var in vGain)
	{
		if (var == Vec2(10, 0))
			return true;
	}
	return false;
}
bool testFourBlockDiagonal2CurrentAtFirst(){
	Board board;
	initFourBlockDiagonal2(board);
	vector<Vec2>vGain;
	board.findGain(6, 4, OUR_TYPE, DIAGONAL2, vGain);
	return checkGainFourBlockDiagonal2(vGain);
}
bool testFourBlockDiagonal2CurrentAtSecond(){
	Board board;
	initFourBlockDiagonal2(board);
	vector<Vec2>vGain;
	board.findGain(7, 3, OUR_TYPE, DIAGONAL2, vGain);
	return checkGainFourBlockDiagonal2(vGain);
}
bool testFourBlockDiagonal2CurrentAtThird(){
	Board board;
	initFourBlockDiagonal2(board);
	vector<Vec2>vGain;
	board.findGain(8, 2, OUR_TYPE, DIAGONAL2, vGain);
	return checkGainFourBlockDiagonal2(vGain);
}
bool testFourBlockDiagonal2CurrentAtFourth(){
	Board board;
	initFourBlockDiagonal2(board);
	vector<Vec2>vGain;
	board.findGain(9, 1, OUR_TYPE, DIAGONAL2, vGain);
	return checkGainFourBlockDiagonal2(vGain);
}
void initFive(Board & board){
	board.setSize(15);
	board.setValue(1, 3,OUR_TYPE);
	board.setValue(1, 4, OUR_TYPE);
	board.setValue(1, 5, OUR_TYPE);
	board.setValue(1, 6, OUR_TYPE);
	board.setValue(1, 7, OUR_TYPE);
}
bool testFive(){
	Board board;
	initFive(board);
	vector<Vec2>vGain;
	if (board.findGain(1, 4, OUR_TYPE, HORIZONTAL, vGain) == FIVE)
		return true;
	return false;
}
void initBoardThreatSearch1(Board *board){
	
	board->setSize(15);
	board->setValue(3, 2, OUR_TYPE);
	board->setValue(4, 2, OUR_TYPE);
	board->setValue(3, 4, OUR_TYPE);
	board->setValue(4, 3, OUR_TYPE);
	
	
}

bool testThreatSearch1(){
	Board board;
	initBoardThreatSearch1(&board);


	vector<Vec2> trace;
	int result=board.threatSearch(3, 2, OUR_TYPE,trace);
	if (result == FIVE)
		return true;
	
	return false;
}
bool testThreatSearch2(){
	Board board;
	board.setSize(15);
	board.setValue(3, 3, OUR_TYPE);
	board.setValue(3, 4, OUR_TYPE);
	board.setValue(4, 5, OUR_TYPE);
	board.setValue(5, 4, OUR_TYPE);
	board.setValue(6, 3, OUR_TYPE);
	board.setValue(7, 2, ENEMY_TYPE);
	board.setValue(6, 4, ENEMY_TYPE);
	board.setValue(6, 5, ENEMY_TYPE);
	board.setValue(5, 6, ENEMY_TYPE);
	
	vector<Vec2> trace;
	int result = board.threatSearch(3, 3, OUR_TYPE, trace);
	
	if (result == FIVE)
		return true;

	return false;
}
bool testThreatSearch3(){
	Board board;
	board.setSize(15);
	board.setValue(6, 7, OUR_TYPE);
	board.setValue(7, 8, OUR_TYPE);
	board.setValue(7, 9, OUR_TYPE);
	board.setValue(6, 9, OUR_TYPE);
	
	vector<Vec2>trace;
	int result =board.threatSearch(7, 8, OUR_TYPE, trace) ;
	return result == FIVE;
}
bool testThreatSearch4(){
	Board board;
	board.setSize(15);
	board.setValue(6, 7, OUR_TYPE);
	board.setValue(7, 8, OUR_TYPE);
	board.setValue(9,8, OUR_TYPE);
	board.setValue(10,7, OUR_TYPE);
	
	vector<Vec2>trace;
	int result = board.threatSearch(6,7, OUR_TYPE, trace);
	
	return result == FIVE;
}
bool testWin(){
	Board board;
	board.setSize(15);
	board.setValue(1, 2, OUR_TYPE);
	board.setValue(1, 3, OUR_TYPE);
	board.setValue(1, 4, OUR_TYPE);
	board.setValue(1, 5, OUR_TYPE);
	board.setValue(1, 6, OUR_TYPE);
	return board.win(1, 3, OUR_TYPE);
}
#endif